home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************
- * *
- * WHERE *
- * *
- * The command line syntax is: *
- * where [starting directory]filename.ext *
- * *
- * Written by Mark S. Ackerman *
- * *
- * Copyright 1984, 1985 by Mark S. Ackerman. Permission is *
- * granted for unlimited copies if not sold or otherwise *
- * exchanged for gain. *
- * *
- * 03/06/87 modified for Megamax C compiler for the Atari ST *
- * J.K.LaPeer *
- * *
- ***************************************************************/
-
-
- /***************************************************************
- * The C header files *
- * These identify library routines like printf() *
- ***************************************************************/
-
- #include <stdio.h> /* standard i/o */
- #include <osbind.h> /* OS bindings */
- #include <string.h> /* String Module bindings */
-
- /***************************************************************
- * Structure for MS-DOS date and time fields *
- * See pages 4-6 and 4-7 of the DOS 2.1 technical *
- * reference manual for more information *
- * This structure is used in the next structure definition *
- ***************************************************************/
-
- struct msdos_date
- {
- unsigned ms_sec : 5; /* time in 2 sec. int (5 bits)*/
- unsigned ms_min : 6; /* minutes (6 bits) */
- unsigned ms_hour : 5; /* hours (5 bits) */
- unsigned : 0;
- unsigned ms_day : 5; /* day of month (5 bits) */
- unsigned ms_month : 4; /* month (4 bits) */
- unsigned ms_year : 7; /* year since 1980 (7 bits) */
- };
-
- /***************************************************************
- * Definition of DOS Disk Transfer Area (DTA) *
- ***************************************************************/
-
- struct DTA
- {
- char DTA_dosinfo[21]; /* used by DOS */
- char DTA_attr; /* file attribute byte */
- struct msdos_date DTA_date; /* date struct. as above */
- long DTA_size; /* file size */
- char DTA_filename[14]; /* file name (w/o path) */
- };
-
-
- /***************************************************************
- * Definitions of constants *
- ***************************************************************/
-
- #define no_type 0x00 /* no bits set on file attribute byte*/
- #define DirType 0x10 /* directory file bit on file
- info word */
- #define no_more_files -13 /* DOS return code for
- no more files */
- #define end_of_string '\0' /* C uses a binary zero to
- signal end of string */
- #define backslash '\\' /* the backslash character */
-
- char *month[] = {
- "Jan","Feb","Mar","Apr","May","Jun",
- "Jul","Aug","Sep","Oct","Nov","Dec"
- };
- char *time_of_day[2] = {"AM","PM"};
-
-
- /***************************************************************
- * Define the type "filename" *
- * to be a string of 51 characters *
- ***************************************************************/
-
- /*typedef char filename[51];*/
-
- /***************************************************************
- * *
- * The following filename strings are used in the program: *
- * *
- * check_string filename to be searched for *
- * filename in the command line) *
- * directory_string directory name to be searched *
- * newdirectory_string directory name to be searched *
- * on next recursive call *
- * current_string temporary string for searching *
- * in a specific directory *
- ***************************************************************/
-
- /***************************************************************
- * Definition of any forward-referenced functions *
- ***************************************************************/
-
- char *DATE();
-
- /***************************************************************
- * Global variables *
- ***************************************************************/
-
- char check_string[51]; /* this string "remembers" user input */
- char datestring[40]; /* print output string for dates */
- long LretCode; /* General Purpose long return code */
-
- /***************************************************************
- * MAIN() -- the beginning of the code *
- ***************************************************************/
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- char directory_string[51]; /* directory to be searched */
- char *incoming_filename; /* address of filename in
- command line argument
- (ie, the filename) */
- char *last_location; /* address of last backslash in
- command line argument */
- char *incoming_string; /* address of
- command line argument */
- int last_directory_char; /* last character
- in directory string */
-
- /********************************************************
- * check number of incoming arguments *
- * if incorrect, write an error message *
- ********************************************************/
-
- if (argc != 2)
- printf
- ("usage is: WHERE [starting directory]filename.ext\n\n");
- else
- {
- /********************************************************
- * incoming_string is set to the first argument in the *
- * command line *
- * The incoming_string is then searched for the last *
- * occurrence of a backslash to find the end of *
- * the directory name. *
- ********************************************************/
-
- incoming_string = *(++argv);
- last_location = rindex(incoming_string,backslash);
-
- /********************************************************
- * If there was not a backslash (and therefore the *
- * beginning directory is the root directory) *
- * begin *
- * copy command line argument into check_string *
- * copy root directory into directory_string *
- * end *
- * else *
- * (if there was a backslash and therefore a beginning *
- * directory specified in the command line) *
- * begin *
- * set the incoming_filename to the next character *
- * past the backslash *
- * copy the incoming_filename into check_string *
- * copy the command line argument into *
- * directory_string *
- * terminate directory_string just after the *
- * last backslash (therefore leaving only the *
- * the directory name in the string) *
- * end *
- ********************************************************/
-
- if (last_location == NULL)
- {
- strcpy(check_string,incoming_string);
- strcpy(directory_string,"\\");
- }
- else
- {
- incoming_filename = last_location + 1;
- strcpy(check_string,incoming_filename);
- strcpy(directory_string,incoming_string);
- last_directory_char = incoming_filename - incoming_string;
- directory_string[last_directory_char] = end_of_string;
- }
- /********************************************************
- * start 'er up *
- ********************************************************/
-
- LOOK(directory_string);
- }
- return;
- }
-
-
- LOOK(directory_string)
-
- /********************************************************
- * LOOK is the recursive procedure in WHERE *
- * It is called once for each subdirectory *
- ********************************************************/
-
- char *directory_string;
- {
- struct DTA current_DTA; /* used to return data from DOS */
- char newdirectory_string[51]; /* the directory to be
- searched on the next
- call to LOOK() */
- char current_string[51]; /* temporary filename
- string for searching for
- directories */
-
- /********************************************************
- * Form current_string by copying directory_string and *
- * and then concatenating "*.*" to look through all *
- * files *
- ********************************************************/
-
- strcpy(current_string,directory_string);
- strcat(current_string,"*.*");
-
- /********************************************************
- * Set the Disk Transfer Area in DOS to the current_DTA *
- * structure *
- * Get the first subdirectory in this directory *
- ********************************************************/
-
- SET_DTA(¤t_DTA);
- GET_FIRST(current_string,DirType);
-
- /********************************************************
- * while there are more subdirectories in this directory *
- * begin *
- * double check for proper directories (see text) *
- * if a directory *
- * begin *
- * set up the newdirectory_string for the *
- * next call to LOOK (see text) *
- * call LOOK *
- * reset Disk Transfer Address (see text) *
- * end *
- * look for next directory *
- * end *
- ********************************************************/
-
- while (LretCode == 0)
- {
- if (current_DTA.DTA_attr == DirType &&
- current_DTA.DTA_filename[0] != '.')
- {
- strcpy(newdirectory_string,directory_string);
- strcat(newdirectory_string,current_DTA.DTA_filename);
- strcat(newdirectory_string,"\\");
- LOOK(newdirectory_string);
- SET_DTA(¤t_DTA);
- }
- GET_NEXT();
- }
-
- /********************************************************
- * if there are no more subdirectories in this directory *
- * look for files *
- * else *
- * print an error message *
- ********************************************************/
- /*
- if (LretCode == no_more_files)
- GET_FILES(directory_string,¤t_DTA);
- else
- printf("problem with looking thru %s\n",directory_string);
- */
- GET_FILES(directory_string,¤t_DTA);
- return;
- }
-
- GET_FILES(directory_string,current_DTA)
-
- /********************************************************
- * GET_FILES *
- * is called once per directory to look for the *
- * actual files matching the search string *
- ********************************************************/
-
- char *directory_string;
- struct DTA *current_DTA;
- {
- char current_string[51];
-
- /********************************************************
- * Form current_string by copying directory_string into *
- * it and then concatenating the check_string onto *
- * the end *
- ********************************************************/
-
- strcpy(current_string,directory_string);
- strcat(current_string,check_string);
-
- /********************************************************
- * Get the first file that matches current_string *
- ********************************************************/
-
- GET_FIRST(current_string,no_type);
-
- /********************************************************
- * while there are more files that match the search *
- * string: *
- * begin *
- * print the file information *
- * get the next file *
- * end *
- ********************************************************/
-
- while (LretCode == 0)
- {
- /* printf(" %s %s%s\n", DATE(&((*current_DTA).DTA_date)),
- directory_string, (*current_DTA).DTA_filename);*/
- printf(" %10ld %s %s%s\n", (*current_DTA).DTA_size,
- DATE(&((*current_DTA).DTA_date)), directory_string,
- (*current_DTA).DTA_filename);
- GET_NEXT();
- }
- /********************************************************
- * if error in looking for a file *
- * print error message and return *
- ********************************************************/
- /*
- if (LretCode != no_more_files)
- printf("problem with looking for %s\n",current_string);
- */ return;
- }
-
-
- GET_NEXT()
- {
- /********************************************************
- * GET_NEXT does an interrupt 21h, function 4Fh *
- ********************************************************/
-
- LretCode = Fsnext();
- return;
- }
-
- SET_DTA(current_DTA)
- struct DTA *current_DTA;
- {
-
- Fsetdta(current_DTA);
- return;
- }
-
- GET_FIRST(search_string,filetype)
- char *search_string;
- int filetype;
- {
-
- LretCode = Fsfirst(search_string, filetype);
- return;
- }
-
-
- char *DATE(dateptr)
- struct msdos_date *dateptr;
- {
- /********************************************************
- * DATE takes the date field from the current DTA *
- * structure and returns a string containing the *
- * information in formatted ASCII *
- ********************************************************/
-
- sprintf(datestring, "%02d-%02d-%2d %02d:%02d %s",
- dateptr->ms_month, dateptr->ms_day,
- dateptr->ms_year+80, (dateptr->ms_hour)%12,
- dateptr->ms_min, time_of_day[((dateptr->ms_hour)/12)]);
- return(datestring);
- }
-